//@author A0100976E
package tasky.tests;
import static org.junit.Assert.*;

import java.io.IOException;
import java.text.ParseException;

import org.junit.Test;

import tasky.history.History;
import tasky.logic.Logic;
import tasky.storage.Storage;

public class LogicTest {

	// error messages
	private static final String ERROR_INVALID_DATE = "Date entered is invalid.\n";
	private static final String ERROR_END_DATE_BEFORE_START_DATE = "End date cannot be before start date\n";
	private static final String ERRORMSG_EMPTY_TASK_CONTENT = "Empty task content entered.\n";
	private static final String INVALID_ID = "Task index is invalid\n";
	
	String add0 = "add ";
	String add1 = "add Do CS2101 Homework -by 04/05/2014";
	String add2 = "add Attend outdoor camp -from 06/05/2014 -to 09/05/2014";
	String add3 = "add CS2103T project V0.1 demo -from 12/05/2014 -to 12/05/2014 -label CS2103T -!";
	String add4 = "add Complete CS1010 Quiz -from 10/05/2014 -to 11/05/2014 -label CS1010";
	String add5 = "add Attend Software Demo talk  -from 13/05/1998 -to 15/05/2014";
	String add6 = "add Complete Developer Guide Draft -by 16/05/2014 -label CS2103T";
	String add7 = "add Complete tutorial 7 for Week8 -by 11/05/2014 -label CS2103T";
	
	String add0Output = ERRORMSG_EMPTY_TASK_CONTENT;
	String add1Output = "\" Do CS2101 Homework -by 04/05/2014 \"  is added successfully.\n";
	String add2Output = "\" Attend outdoor camp -from 06/05/2014 -to 09/05/2014 \"  is added successfully.\n";
	String add3Output = "\" CS2103T project V0.1 demo -from 12/05/2014 -to 12/05/2014 -label CS2103T -! \"  is added successfully.\n";
	String add4Output = "\" Complete CS1010 Quiz -from 10/05/2014 -to 11/05/2014 -label CS1010 \"  is added successfully.\n";
	String add5Output = "\" Attend Software Demo talk  -from 13/05/1998 -to 15/05/2014 \"  is added successfully.\n";
	String add6Output = "\" Complete Developer Guide Draft -by 16/05/2014 -label CS2103T \"  is added successfully.\n";
	String add7Output = "\" Complete tutorial 7 for Week8 -by 11/05/2014 -label CS2103T \"  is added successfully.\n";

	// Boundary test case input for add
	String addBoundaryInput1 = "add testing boundary 1 -by 29/02/2014"; // not
																		// leap
																		// year
	String addBoundaryInput2 = "add testing boundary 2 -by 29/02/2012"; // leap
																		// year
	String addBoundaryInput3 = "add testing boundary 3 -by 32/07/2012"; // number
																		// is
																		// beyond(too
																		// big)
																		// the
																		// accepted
																		// range
	String addBoundaryInput4 = "add testing boundary 4 -by 30/07/2012"; // number
																		// is on
																		// the
																		// border
																		// of
																		// being
																		// accepted
	String addBoundaryInput5 = "add testing boundary 4 -by -30/07/2012"; // number
																			// is
																			// beyond(too
																			// small)
																			// the
																			// accepted
																			// range
	// Boundary test case output for add
	String addBoundaryOutput1 = ERROR_INVALID_DATE;
	String addBoundaryOutput2 = "\" testing boundary 2 -by 29/02/2012 \"  is added successfully.\n";
	String addBoundaryOutput3 = ERROR_INVALID_DATE;
	String addBoundaryOutput4 = "\" testing boundary 4 -by 30/07/2012 \"  is added successfully.\n";
	String addBoundaryOutput5 = ERROR_INVALID_DATE;

	// Boundary test case input for timed task
	String timedTaskBoundaryInput1 = "add timed task -from 12/12/12-13:00 -to 12/12/12-13:30"; // within
																								// timed
																								// boundary
	String timedTaskBoundaryInput2 = "add timed task -from 12/12/12-13:00 -to 12/12/12"; // end
																							// date
																							// before
																							// start
																							// date
	String timedTaskBoundaryInput3 = "add timed task -from 12/12/12-13:00 -to -12/12/12"; // invalid
																							// end
																							// date
	String timedTaskBoundaryInput4 = "add timed task -from -12/12/12-13:00 -to 12/12/12"; // invalid
																							// start
																							// date
	String timedTaskBoundaryInput5 = "add timed task -from 30/7/12-13:00 -to 30/7/12--13:30"; // invalid
																								// time
	// Boundary test case output for timed task
	String timedTaskBoundaryOutput1 = "\" timed task -from 12/12/12-13:00 -to 12/12/12-13:30 \"  is added successfully.\n";
	String timedTaskBoundaryOutput2 = ERROR_END_DATE_BEFORE_START_DATE;
	String timedTaskBoundaryOutput3 = ERROR_INVALID_DATE;
	String timedTaskBoundaryOutput4 = ERROR_INVALID_DATE;
	String timedTaskBoundaryOutput5 = ERROR_INVALID_DATE;

	String deleteAll = "delete all";
	String deleteAllOutput = "All tasks deleted\n";
	
	
	String done1 = "done 1";
	String done2 = "done 2";
	String done3 = "search -done";

	String done1Output = "Task 1 is set to done\n";
	String done2Output = "Task 2 is set to done\n";
	String done3Output = "Searching tasks which are Done:\n1. Do CS2101 Homework\n2. Attend outdoor camp\n";
	
	@Test
	public void testDone() throws ClassNotFoundException, IOException,
			ParseException, InterruptedException {
		Storage s = Storage.getInstance();
		History h = new History();
		Logic l = new Logic(s,h);
		l.processUserInput(add1);
		l.processUserInput(add2);
		l.processUserInput(add3);
		l.processUserInput(add4);

		assertEquals(done1Output, l.processUserInput(done1).getOutput());
		assertEquals(done2Output, l.processUserInput(done2).getOutput());
		assertEquals(done3Output, l.processUserInput(done3).getOutput());

		assertEquals(deleteAllOutput, l.processUserInput(deleteAll).getOutput());

	}
	
	String undone1 = "undone 1";
	String undone2 = "search -done";
	String undone3 = "search -undone";

	String undone1Output = "Task 1 is set to undone\n";
	String undone2Output = "Searching tasks which are Done:\n2. Attend outdoor camp\n";
	String undone3Output = "Searching tasks which are Undone:\n1. Do CS2101 Homework\n3. CS2103T project V0.1 demo\n4. Complete CS1010 Quiz\n";


	@Test
	public void testUndone() throws ClassNotFoundException, IOException,
			ParseException, InterruptedException {
		Storage s = Storage.getInstance();
		History h = new History();
		Logic l = new Logic(s, h);
		assertEquals(deleteAllOutput, l.processUserInput(deleteAll).getOutput());
		l.processUserInput(add1);
		l.processUserInput(add2);
		l.processUserInput(add3);
		l.processUserInput(add4);

		assertEquals(done1Output, l.processUserInput(done1).getOutput());
		assertEquals(done2Output, l.processUserInput(done2).getOutput());
		assertEquals(undone1Output, l.processUserInput(undone1).getOutput());
		assertEquals(undone2Output, l.processUserInput(undone2).getOutput());
		assertEquals(undone3Output, l.processUserInput(undone3).getOutput());

		assertEquals(deleteAllOutput, l.processUserInput(deleteAll).getOutput());

	}

	@Test
	public void testAdd() throws IOException, ParseException,
			ClassNotFoundException, InterruptedException {
		Storage s = Storage.getInstance();
		History h = new History();
		Logic l = new Logic(s, h);
		
		assertEquals(add0Output, l.processUserInput(add0).getOutput());
		assertEquals(add1Output, l.processUserInput(add1).getOutput());
		assertEquals(add2Output, l.processUserInput(add2).getOutput());
		assertEquals(add3Output, l.processUserInput(add3).getOutput());
		assertEquals(add4Output, l.processUserInput(add4).getOutput());
		assertEquals(add5Output, l.processUserInput(add5).getOutput());
		assertEquals(add6Output, l.processUserInput(add6).getOutput());
		assertEquals(add7Output, l.processUserInput(add7).getOutput());

		// To test for boundary cases for add tasks
		
		assertEquals(addBoundaryOutput1, l.processUserInput(addBoundaryInput1).getOutput());
		assertEquals(addBoundaryOutput2, l.processUserInput(addBoundaryInput2).getOutput());
		assertEquals(addBoundaryOutput3, l.processUserInput(addBoundaryInput3).getOutput());
		assertEquals(addBoundaryOutput4, l.processUserInput(addBoundaryInput4).getOutput());
		assertEquals(addBoundaryOutput5, l.processUserInput(addBoundaryInput5).getOutput());

		// To test for boundary cases for timed tasks
		assertEquals(timedTaskBoundaryOutput1,
				l.processUserInput(timedTaskBoundaryInput1).getOutput());
		assertEquals(timedTaskBoundaryOutput2,
				l.processUserInput(timedTaskBoundaryInput2).getOutput());
		assertEquals(timedTaskBoundaryOutput3,
				l.processUserInput(timedTaskBoundaryInput3).getOutput());
		assertEquals(timedTaskBoundaryOutput4,
				l.processUserInput(timedTaskBoundaryInput4).getOutput());
		assertEquals(timedTaskBoundaryOutput5,
				l.processUserInput(timedTaskBoundaryInput5).getOutput());
		assertEquals(true,
						l.processUserInput(timedTaskBoundaryInput5).isError());

		assertEquals(deleteAllOutput, l.processUserInput(deleteAll).getOutput());

	}
	
	// test case for display command
	
	String displayInput = "display";
	String displayNoneOutput = "Here are your tasks:\nThere is no tasks recorded.\n";
	String displayOutput = "Here are your tasks:\n1. Do CS2101 Homework by 04/05/2014\n" + "2. Attend outdoor camp from 06/05/2014 to 09/05/2014\n"
			+ "3. CS2103T project V0.1 demo from 12/05/2014 to 12/05/2014\n" + "4. Complete CS1010 Quiz from 10/05/2014 to 11/05/2014\n"
			+ "5. Attend Software Demo talk from 13/05/1998 to 15/05/2014\n"
			+ "6. Complete Developer Guide Draft by 16/05/2014\n"
			+ "7. Complete tutorial 7 for Week8 by 11/05/2014\n";
	
	@Test
	public void testDisplay() throws IOException, ParseException,
			ClassNotFoundException, InterruptedException {
		Storage s = Storage.getInstance();
		History h = new History();
		Logic l = new Logic(s, h);
		
		assertEquals(displayNoneOutput,l.processUserInput(displayInput).getOutput());
		l.processUserInput(add1);
		l.processUserInput(add2);
		l.processUserInput(add3);
		l.processUserInput(add4);
		l.processUserInput(add5);
		l.processUserInput(add6);
		l.processUserInput(add7);

		assertEquals(displayOutput, l.processUserInput(displayInput).getOutput());

		assertEquals(deleteAllOutput, l.processUserInput(deleteAll).getOutput());

	}
	
	// test case for edit command
	String editInput0 = "edit 1";
	String editInput1 = "edit 1 Complete tutorial 1000000000000000000000000000";
	String editInput2 = "edit 6 Complete Developer Guide Draft for CS2103T -by 16/03/2014 -label CS2103T";
	String editInput3 = "edit 1000000000 THIS SHOULD NOT COME OUT!";	//Equivalent partition test case when the index provided is invalid
	String editInput4 = "edit abc hello";	//Equivalent partition test case when the index provided is not an integer
	
	String editOutput0 = ERRORMSG_EMPTY_TASK_CONTENT;
	String editOutput1 = "Here are your tasks:\n1. Complete tutorial 1000000000000000000000000000\n" + "2. Attend outdoor camp from 06/05/2014 to 09/05/2014\n"
			+ "3. CS2103T project V0.1 demo from 12/05/2014 to 12/05/2014\n" + "4. Complete CS1010 Quiz from 10/05/2014 to 11/05/2014\n"
			+ "5. Attend Software Demo talk from 13/05/1998 to 15/05/2014\n"
			+ "6. Complete Developer Guide Draft by 16/05/2014\n"
			+ "7. Complete tutorial 7 for Week8 by 11/05/2014\n";
	String editOutput2 = "Here are your tasks:\n1. Complete tutorial 1000000000000000000000000000\n" + "2. Attend outdoor camp from 06/05/2014 to 09/05/2014\n"
			+ "3. CS2103T project V0.1 demo from 12/05/2014 to 12/05/2014\n" + "4. Complete CS1010 Quiz from 10/05/2014 to 11/05/2014\n"
			+ "5. Attend Software Demo talk from 13/05/1998 to 15/05/2014\n"
			+ "6. Complete Developer Guide Draft for CS2103T by 16/03/2014\n"
			+ "7. Complete tutorial 7 for Week8 by 11/05/2014\n";
	String editOutput3 = INVALID_ID;
	String editOutput4 = INVALID_ID;

	@Test
	public void testEdit() throws IOException, ParseException,
			ClassNotFoundException, InterruptedException {
		Storage s = Storage.getInstance();
		History h = new History();
		Logic l = new Logic(s, h);
		l.processUserInput(add1);
		l.processUserInput(add2);
		l.processUserInput(add3);
		l.processUserInput(add4);
		l.processUserInput(add5);
		l.processUserInput(add6);
		l.processUserInput(add7);
		
		l.processUserInput(editInput0);
		assertEquals(editOutput0,l.processUserInput(editInput0).getOutput());
		l.processUserInput(editInput1);
		
		assertEquals(editOutput1, l.processUserInput(displayInput).getOutput());
		l.processUserInput(editInput2);
		assertEquals(editOutput2, l.processUserInput(displayInput).getOutput());
		assertEquals(editOutput3, l.processUserInput(editInput3).getOutput());
		assertEquals(editOutput4, l.processUserInput(editInput4).getOutput());

		assertEquals(deleteAllOutput, l.processUserInput(deleteAll).getOutput());
	}
	
	
	String searchInput1 = "search -date 04/05/2014";
	String searchInput2 = "search -date 16/05/2014";
	String searchInput3 = "search -from 12/05/2014";
	String searchInput4 = "search -to 15/05/2014";
	String searchInput5 = "search -to 11/05/2014";
	String searchInput6 = "search -!";
	String searchInput7 = "search -label CS2103T";
	String searchInput8 = "search -label RANDOM";
	String searchInput9 = "search CS2103T";
	String searchInput10 = "search Complete";
	String searchInput11 = "search Complete Developer Guide Draft ";
	String searchInput12 = "search -date";	//Equivalent partition test case when there is no date entered
	String searchInput13 = "search -from";	//Equivalent partition test case when there is no date entered
	String searchInput14 = "search -to";	//Equivalent partition test case when there is no date entered
	String searchInput15 = "search";
	String searchInput16 = "search -date -1/-1/2014"; //Equivalent partition test case when date entered is invalid
	String searchInput17 = "search -from 5/43/2014";  //Equivalent partition test case when month entered exceeds 12
	String searchInput18 = "search -to 13/random/2014";//Equivalent partition test case when the month entered is invalid 
	
	String searchOutput1 = "Searching tasks that ends on: 04/05/2014\n1.[00:00] Do CS2101 Homework\n";
	String searchOutput2 = "Searching tasks that ends on: 16/05/2014\n6.[00:00] Complete Developer Guide Draft\n";
	String searchOutput3 = "Searching tasks that starts from: 12/05/2014\n3.[00:00] CS2103T project V0.1 demo\n";
	String searchOutput4 = "Searching tasks that ends on: 15/05/2014\n5.[00:00] Attend Software Demo talk\n";
	String searchOutput5 = "Searching tasks that ends on: 11/05/2014\n4.[00:00] Complete CS1010 Quiz\n";
	String searchOutput6 = "Searching tasks with priority:\n3. CS2103T project V0.1 demo\n";
	String searchOutput7 = "Searching tasks with label: CS2103T\n3. CS2103T project V0.1 demo\n6. Complete Developer Guide Draft\n7. Complete tutorial 7 for Week8\n";
	String searchOutput8 = "Searching tasks with label: RANDOM\n-None-\n";
	String searchOutput9 = "Searching \"CS2103T\"\n3. CS2103T project V0.1 demo\n";
	String searchOutput10= "Searching \"Complete\"\n4. Complete CS1010 Quiz\n6. Complete Developer Guide Draft\n7. Complete tutorial 7 for Week8\n";
	String searchOutput11 = "Searching \"Complete Developer Guide Draft\"\n6. Complete Developer Guide Draft\n";
	String searchOutput12 = ERROR_INVALID_DATE;
	String searchOutput13 = ERROR_INVALID_DATE;
	String searchOutput14 = ERROR_INVALID_DATE;
	String searchOutput15 = "Searching for all tasks:\n1. Do CS2101 Homework\n" + "2. Attend outdoor camp\n"
			+ "3. CS2103T project V0.1 demo\n" + "4. Complete CS1010 Quiz\n"
			+ "5. Attend Software Demo talk\n"
			+ "6. Complete Developer Guide Draft\n"
			+ "7. Complete tutorial 7 for Week8\n";
	String searchOutput16 = ERROR_INVALID_DATE;
	String searchOutput17 = ERROR_INVALID_DATE;
	String searchOutput18 = ERROR_INVALID_DATE;
	@Test
	public void testSearch() throws IOException, ParseException,
			ClassNotFoundException, InterruptedException {
		Storage s = Storage.getInstance();
		History h = new History();
		Logic l = new Logic(s, h);

		l.processUserInput(add1);
		l.processUserInput(add2);
		l.processUserInput(add3);
		l.processUserInput(add4);
		l.processUserInput(add5);
		l.processUserInput(add6);
		l.processUserInput(add7);
		assertEquals(searchOutput1,l.processUserInput(searchInput1).getOutput());
		assertEquals(searchOutput2,l.processUserInput(searchInput2).getOutput());
		assertEquals(searchOutput3,l.processUserInput(searchInput3).getOutput());
		assertEquals(searchOutput4,l.processUserInput(searchInput4).getOutput());
		assertEquals(searchOutput5,l.processUserInput(searchInput5).getOutput());
		assertEquals(searchOutput6,l.processUserInput(searchInput6).getOutput());
		assertEquals(searchOutput7,l.processUserInput(searchInput7).getOutput());
		assertEquals(searchOutput8,l.processUserInput(searchInput8).getOutput());
		assertEquals(searchOutput9,l.processUserInput(searchInput9).getOutput());
		assertEquals(searchOutput10,l.processUserInput(searchInput10).getOutput());
		assertEquals(searchOutput11,l.processUserInput(searchInput11).getOutput());
		assertEquals(searchOutput12,l.processUserInput(searchInput12).getOutput());
		assertEquals(searchOutput13,l.processUserInput(searchInput13).getOutput());
		assertEquals(searchOutput14,l.processUserInput(searchInput14).getOutput());
		assertEquals(searchOutput15,l.processUserInput(searchInput15).getOutput());
		assertEquals(searchOutput16,l.processUserInput(searchInput16).getOutput());
		assertEquals(searchOutput17,l.processUserInput(searchInput17).getOutput());
		assertEquals(searchOutput18,l.processUserInput(searchInput18).getOutput());

	}

}
